#include "bsp_usart2.h"

UART_HandleTypeDef huart2;   // USART2句柄
uart1_dev_t uart1_dev = {0}; // 接收数据结构体

void bsp_usart2_init(uint32_t baudrate)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* clk 配置 */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_USART2_CLK_ENABLE();

    /* gpio 配置 */
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;       // 复用推挽（串口发送）
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // 配置PA3（RX）为浮空输入
    GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 输入模式
    GPIO_InitStruct.Pull = GPIO_NOPULL;     // 浮空（不上下拉）
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    huart2.Instance = USART2;
    huart2.Init.BaudRate = baudrate;                 // 波特率（如115200）
    huart2.Init.WordLength = UART_WORDLENGTH_8B;     // 8位数据位
    huart2.Init.StopBits = UART_STOPBITS_1;          // 1位停止位
    huart2.Init.Parity = HAL_UART_PARITY_NONE;       // 无校验位
    huart2.Init.Mode = UART_MODE_TX_RX;              // 收发模式
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;     // 无硬件流控
    huart2.Init.OverSampling = UART_OVERSAMPLING_16; // 16倍过采样
    HAL_UART_Init(&huart2);

    HAL_NVIC_SetPriority(USART2_IRQn, 3, 0); // 抢占优先级3（低于定时器，避免冲突）
    HAL_NVIC_EnableIRQ(USART2_IRQn);         // 使能USART2中断

    HAL_UART_Receive_IT(&huart2, &uart1_dev.rx_buf[uart1_dev.rx_len], 1); // 开启接收中断（每次接收1个字节，触发中断后自动重新开启）
}

// 发送单个字节
void uart1_send_byte(uint8_t *data, uint8_t len)
{
    HAL_UART_Transmit(&huart2, data, len, 100); // 超时时间100ms
}

// USART2中断服务函数（HAL库入口）
void USART2_IRQHandler(void)
{
    HAL_UART_IRQHandler(&huart2);
}

// 接收完成回调函数（每次接收1字节后触发）
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART2)
    {
        // 接收长度加1（确保不超过缓冲区大小）
        uart1_dev.rx_len++;
        if (uart1_dev.rx_len >= UART1_RX_BUF_SIZE)
        {
            uart1_dev.rx_len = 0; // 缓冲区满则清零（避免溢出）
        }

        // 示例：以换行符'\n'作为接收结束标志（可修改为其他标志）
        if (uart1_dev.rx_buf[uart1_dev.rx_len - 1] == '\n')
        {
            uart1_dev.rx_flag = 1; // 置位接收完成标志
        }

        // 重新开启接收中断（关键：每次接收后需手动重启）
        HAL_UART_Receive_IT(&huart2, &uart1_dev.rx_buf[uart1_dev.rx_len], 1);
    }
}

int fputc(int ch, FILE *f)
{
    HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 100); // 通过USART2发送字符（阻塞模式，超时100ms）
    return ch;
}
